<?php defined('BASEPATH') OR exit('No direct script access allowed');

class Ajax extends MY_Controller {
	
	function __construct(){
		parent::__construct();
		$this->load->model('misc_model');
		$this->load->model('user_model');
		$this->load->model('poll_model');

		if(ENVIRONMENT != 'development'){
			// Ajax request만 허용
			if( ! $this->input->is_ajax_request())
			{
				set_status_header(403);
				echo "Invalid Access";
				exit;
			}
		}
	}
	
	/**
	 * 사용자
	 */
	function login(){
		$this->load->library('form_validation');
		if($this->form_validation->run('login'))
		{
			$username = $this->input->post('username');
			$password = $this->input->post('password');
			if($this->user_model->login($username, $password) === TRUE)
			{
				$redirect_to = $this->input->post('redirect_to');
				if(!$redirect_to)
					$redirect_to = site_url($this->user_lib->is_admin() ? 'admin':'');
				return ajax_ok(array('redirect_to' => $redirect_to));
			}
			return ajax_error('로그인에 실패했습니다. 사용자명과 패스워드를 확인해 주세요.');
		}
		ajax_result('error', NULL, $this->form_validation->get_error_array());
	}
	
	function register(){
		$this->load->library('form_validation');
		if($this->form_validation->run('register'))
		{
			$this->load->helper('array');

			// DB Schema에 해당하는 필드만 추출
			$keys = $this->form_validation->get_config_rules_group_keys('register');
			$post = elements($keys, $this->input->post());
			unset($post['password_confirm']);
			
			// 사용자명 중복 검사			
			if($this->user_model->get_user_by_username($post['username']) != FALSE)
				return ajax_result('error', NULL, array('username' => '동일한 사용자명이 존재합니다.'));
			
			// 주소 유효성 검사
			$addr = array();
			$parent = ADDRESS_NO_PARENT;
			for($i=1; $i<=3; $i++)
			{
				$tmp = $this->misc_model->get_address_by_id($post["address{$i}_id"]);
				if($tmp == FALSE || $tmp->belongs_to != $parent)
					return ajax_result('error', NULL, array("address{$i}_id" => '잘못된 주소입니다.'));
				$addr[] = $tmp->name;
				$parent = $tmp->id;
			}	
			$post['address_str'] = implode(' ', $addr);
			
			if($this->user_model->register($post))
			{
				$this->user_model->login($post['username'], $post['password']);
				return ajax_ok(array('redirect_to' => site_url('')));
			}
		}
		$errors = $this->form_validation->get_error_array();
		if(isset($errors['birthday']))
			$errors['birthday[]'] = $errors['birthday'];
		ajax_result('error', NULL, $errors);
	}

	function check_username()
	{
		$this->load->library('form_validation');
		$this->form_validation->set_rules('username', '사용자명', 'required|alpha_dash|min_length['.USERNAME_MIN_LENGTH.']|max_length['.USERNAME_MAX_LENGTH.']');
		if($this->form_validation->run() && $this->user_model->check_username($username) === FALSE)
			return ajax_ok(); 
		return ajax_error($this->form_validation->error('username'));
	}
	
	/**
	 * 설문 답
	 */
	
	function create_vote(){
		$this->load->model('poll_model');
		$this->load->helper('array');
		$this->load->helper('date');
		$post = $this->input->post();
		
		$poll_id = mysql_real_escape_string($post['poll_id']);
		$user = $this->user_lib->get_current_user();
		
		$question_numbers = $this->poll_model->get_number_of_questions($poll_id);
		if( ! $question_numbers)
			return ajax_error("Invalid Input");
		
		$answers = array();
		foreach($post as $k => $val)
		{
			if(substr($k, 0, 7) == 'answers' && trim($val) != '' )
			{
				$answers[] = $val;
			}
		}
			
		if($question_numbers != count($answers))
			return ajax_error("모든 문항에 답해주십시오.");
		
		$vote_rows = $this->poll_model->create_vote($poll_id, $user ? $user->id : NULL, $answers);
		
		$message = '완료되었습니다.';
		if($user){
			$plus_score = 20 + count($answers);	//기본 10점 + 문항당 1점
			$this->user_model->increase_vote_score($user->id, $plus_score);
			$message .= '  설문 응답 점수가 '.$plus_score.' 증가했습니다.';
		}
			
		return ajax_result('ok', $message, array('redirect_to' => site_url('')));
	}
	
	/**
	 * 설문
	 */
	function create_poll(){
		if( ! ($user = $this->user_lib->get_current_user()))
			return ajax_error('Permission denied');
		
		$this->load->library('form_validation');
		
		if($this->form_validation->run('create_poll')){
			$this->load->model('poll_model');
			$this->load->helper('array');
			$this->load->helper('date');
			
			$post = $this->input->post();
			
			// 공통 항목 추출
			$poll_common_keys = array('title', 'category', 'keyword', 'poll_start', 'poll_end', 'mid_show', 'max_people', 'type', 'daily_start', 'daily_end', 'location', 'login_required');
			$poll_common = elements($poll_common_keys, $post);
			$poll_common['user_id'] = $user->id;
			
			$datetime_fields = $this->config->item('datetime_fields');
			foreach($poll_common as $k => $i)
			{
				if($i === FALSE || $i === NULL)
				{
					unset($poll_common[$k]);
				}
				else if(in_array($k, $datetime_fields)) 
				{
					$time = strtotime($i);
					if(substr($k, 0, 5) == 'daily')
						$poll_common[$k] = date("H:i", $time);
					else
						$poll_common[$k] = date("Y-m-d H:i:s", $time);
				}
			}
			
			// 기타 참여조건 추출
			$conditions = array();
			$questions_from_cond = array();
			if(isset($post['condition_rules']) && is_array($post['condition_rules']))
			{
				foreach($post['condition_rules'] as $cond){
					$condition = NULL;
					mb_parse_str($cond, $condition);
					
					if(in_array('address', $condition['condition']))
					{
						$condition['address_id'] = max($condition['address1_id'], $condition['address2_id'], $condition['address3_id']);
						unset($condition['address1_id'], $condition['address2_id'], $condition['address3_id']);
					}
					
					foreach($condition['condition'] as $k){
						$idx = ($k == 'address') ? 'address_id':$k;
						if( ! isset($questions_from_cond[$idx]))
							$questions_from_cond[$idx] = array();
						$questions_from_cond[$idx][] = $condition[$idx];
					}
						
					unset($condition['condition']);
					$conditions[] = $condition;
				}
			}
			
			// 문항 생성
			$questions = array();
			$question_titles = array(
				'address_id' => '거주지를',
				'gender' => '성별을',
				'education' => '최종학력을',
				'age_range' => '연령대를'
			);
			
			// 참여조건을 문항으로 변환
			foreach($questions_from_cond as $k => $i){
				$cond = array_unique($i);
				sort($cond);
				$question = array();
				$question['title'] = '귀하의 '.$question_titles[$k].' 선택해 주십시오.';
				if($k == 'address_id')
				{
					$question['options'] = array();
					foreach($cond as $i)
						$question['options'][] = $this->misc_model->get_address_str_by_id($i);
				}
				else
				{
					$question['options'] = elements($cond, $this->config->item($k));
				}
				$question['type'] = count($cond) > 5 ? 'select' : 'choose';
				$questions[] = $question;
			}
			
			// 문항 추출
			foreach($post['questions'] as $q){
				mb_parse_str($q, $question);
				if(substr($question['type'], 0, 6) == 'choose')
					$question['type'] = 'choose';
				$questions[] = $question;
			}
			$poll_id = $this->poll_model->create_common($poll_common);
			
			$question_rows = $this->poll_model->create_questions($poll_id, $questions);
			if(  ! empty($conditions) )
				$this->poll_model->create_conditions($poll_id, $conditions);
			
			$plus_score = 30 + $question_rows;
			$this->user_model->increase_create_score($user->id, $plus_score);
			
			return ajax_result('ok', "완료되었습니다. 설문 작성 점수가 {$plus_score} 증가했습니다.", array('redirect_to' => site_url('')));
		}
		$errors = $this->form_validation->get_error_array();
		if(isset($errors['questions[]'])){
			$errors['questions_error'] = $errors['questions[]'];
			unset($errors['questions[]']);
		}
		ajax_result('error', NULL, $errors);
	}

	/**
	 * GPS좌표정보 추가
	 */
	function create_location()
	{
		$this->load->library('form_validation');
		$this->load->helper('array');
		
		if($this->form_validation->run('create_location')){
			$post = $this->input->post();
			$post['address_str'] = $post['address'].' '.$post['name'];
			$post['address_id'] = max($post['address_id']);
			
			$keys = array('address_id', 'address_str', 'lat', 'lng', 'radius');
			$data = elements($keys, $post);
			
			$res = $this->misc_model->create_location($data);
			
			$redirect_to = empty($post['redirect_to']) ? $this->agent->referrer() : $post['redirect_to'];
			
			return ajax_ok(array('redirect_to' => $redirect_to));
		}
		$errors = $this->form_validation->get_error_array();
		return ajax_result('error', NULL, $errors);
	}
	
	function search_location_by_str()
	{
		$str = $this->input->post('text');
		if( empty($str))
			return ajax_error('no input');
		
		$str = mysql_real_escape_string($str);
		
		$res = $this->misc_model->get_locations_by_str($str);
		return ajax_ok($res);
	}
	
	
	/**
	 * 기타
	 */
	
	/**
	 * 행정구역 ID를 입력받아 한 단계 밑의 행정구역의 목록을 리턴한다.
	 * ADDRESS_NO_PARENT(='0000000000')를 입력하면 최상위 주소 출력 (config/constants.php 참조)
	 * @author	박지수
	 * @param	String
	 */
	function get_address_children($id){
		if( is_numeric($id) && strlen($id) == ADDRESS_ID_LENGTH ){
			if($res = $this->misc_model->get_address_children($id)){
				return ajax_ok($res);
			}else{
				return ajax_error('no result');
			}
		}else{
			return ajax_error('invalid input');
		}
	}
	
	/**
	 * 구글맵 address_components 객체 받아서 자체 DB 행정구역 단위로 변환
	 * @author 박지수
	 */
	function convert_address_components()
	{
		if( ! is_array($addr = $this->input->post('address_components')))
			return ajax_error('invalid input');
		
		$addr = array_reverse($addr);
		
		do{
			$i = array_shift($addr);
		}
		while( !empty($addr) && !in_array('locality', $i['types']) && !in_array('administrative_area_level_1', $i['types']));
			
		if(empty($addr))
			return ajax_error('empty input');
		
		$data = array();
		$result = array();
		
		if(in_array('locality', $i['types']))
		{
			// 서울시, 기타 광역시
			$data[0] = preg_replace('/특별시|광역시/', '시', $i['long_name']);
			$in_city = true;
		}
		else
		{
			// 도 단위
			$data[0] = $i['long_name'];
			$in_city = false;
		}
		
		$data[2] = array();
		while(!empty($addr))
		{
			$i = array_shift($addr);
			$last = mb_substr($i['long_name'], -1);
			switch($last)
			{
				case '시':
				case '군':
					$data[1] = $i['long_name'];
					break;
				case '구':
					if($in_city)
						$data[1] = $i['long_name'];
					break;
				default:
					if(in_array('sublocality', $i['types']))
						$data[2][] = preg_replace('/\d(동|리)([\s ]|$)/', '$1$2', $i['long_name']);
//					else if(in_array('street_address', $i['types']))
//						$data['address'] = $i['long_name'];
//					else if(in_array('establishment', $i['types']))
//						$data['name'] = $i['long_name'];
			}
			
		}
//		if(empty($data[2]) || empty($data['address']))
//			return ajax_error('way too vague');
		
		$data[2] = implode(' ', $data[2]); 
		$ids = $this->misc_model->get_address_ids_by_components($data);
		if( $ids )
		{
			$res = array();
			foreach($ids as $k => $id){
				$res[$id] = ($k <= 1) ? $this->misc_model->get_address_children($id) : array();
			}
			return ajax_ok($res);
		}
		else
			return ajax_error("데이터베이스에서 해당 지역을 찾지 못했습니다.");
	}

	function get_default_polls($start_id = 0)
	{
		$lat = $this->input->post('lat');
		$lng = $this->input->post('lng');
		if( ! $lat || ! $lng)		
			return ajax_error('현재위치를 입력해 주세요.');
			
		$polls = $this->poll_model->get_available_polls($lat, $lng, $start_id);
		return ajax_ok($polls);
	}

	function can_user_vote()
	{
		$this->load->library('poll_lib');
		
		$poll_id = $this->input->post('poll_id');
		$user_id = $this->user_lib->get_current_user_id();
		$lat = $this->input->post('lat');
		$lng = $this->input->post('lng');
		
		$vote_code = $this->poll_lib->can_user_vote($poll_id, $user_id, $lat, $lng);
		if($vote_code === POLL_OK)
			return ajax_ok();
		
		$vote_msg = $this->config->item('votable_messages');
		return ajax_error($vote_msg[$vote_code]);
	}
}